/*
 * CollisionWorld detects and handles the line segment intersections
 */

#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <stdio.h>
#include <vector>

#include "IntersectionDetection.h"
#include "Line.h"
#include "Vec.h"

using namespace std;

// Generates a random double from the range [0, 1)
static inline double randDouble() {
	return (double) rand() / RAND_MAX;
}

vector<Line*> generateTestCase(int n_lines, double max_len, int seed) {
  srand(seed);
	double width = ((double) BOX_XMAX - BOX_XMIN);
	double height = ((double) BOX_YMAX - BOX_YMIN);
	const double PI = 3.1415926535897;
	vector<Line*> lines;
	for(int i = 0; i < n_lines; i++) {
		Line *l = new Line;
		l->p1.x = width * randDouble();
		l->p1.y = height * randDouble();
		while(1) {
			double theta = 2 * PI * randDouble();
			double len = randDouble();
			// Bias the length to not be too small
			len = .95 * sqrt(len) + .05;
      if(len < .4)
        l->isGray = true;
      else
        l->isGray = false;
			len *= max_len;
			l->p2.x = l->p1.x + len * cos(theta);
			l->p2.y = l->p1.y + len * sin(theta);
			// Make sure we are inside the box, otherwise repeat
			if(l->p2.x >= 0 && l->p2.x < width && l->p2.y >= 0 && l->p2.y < height) break;
		}
		// Give it a velocity and a color
		l->vel = Vec(randDouble() / 2000., randDouble() / 500.);
		if(rand() % 2) l->vel.x *= -1;
		if(rand() % 2) l->vel.y *= -1;
		// New segments cant intersect previous segments
		bool collision = false;
		for(int j = 0; j < i; j++) {
			if(intersectLines(l->p1, l->p2, lines[j]->p1, lines[j]->p2)) {
				collision = true;
				break;
			}
		}
		if(collision) {
      i--;
      delete l;
    } else { 
      lines.push_back(l);
    }
	}
  for(int i = 0; i < n_lines; i++) {
    lines[i]->p1.x += BOX_XMIN;
    lines[i]->p1.y += BOX_YMIN;
    lines[i]->p2.x += BOX_XMIN;
    lines[i]->p2.y += BOX_YMIN;
  }
	return lines;
}
